package com.tianruan.dc.common.annotation;

import com.tianruan.dc.common.annotation.condition.ApiVersionCondition;
import com.tianruan.dc.common.exception.ApiVersionException;
import com.tianruan.dc.common.utils.ApiVersionUtil;
import com.tianruan.dc.common.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @PS
 */
@Slf4j
@Aspect
@Component
public class ApiVersionAspect {

    @Pointcut("@within(ApiVersion) || @annotation(ApiVersion)")
    public void apiVersionPointCut() {

    }

    @Before("apiVersionPointCut()")
    public void before(JoinPoint point) throws ApiVersionException {

        // 获取apiVersion对象
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        ApiVersion apiVersion = method.getAnnotation(ApiVersion.class);
        if (apiVersion == null) {
            Object object = point.getTarget();
            apiVersion = object.getClass().getAnnotation(ApiVersion.class);
            if (apiVersion == null) {
                return;
            }
        }
        // 获取request对象
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) requestAttributes;
        if (sra == null) {
            return;
        }
        HttpServletRequest request = sra.getRequest();

        // 获取uri中的版本号
        String[] bomVersionList = request.getRequestURI().split("/");
        for (String version: bomVersionList) {
            // 校验版本格式是否正确
            boolean matches = version.matches(ApiVersionCondition.VERSION_PREFIX);
            if (matches) {
                String version_t = version.substring(1);
                String min = apiVersion.min();
                String max = apiVersion.max();
                String start = apiVersion.start();
                String end = apiVersion.end();

                // 判断最低版本号要求
                if (StringUtils.isNotBlank(min) && ApiVersionUtil.compareVersion(version, min) < 0) {
                    throw new ApiVersionException(202001, "当前应用版本过低，请先更新应用");
                }
                // 判断最大版本号要求
                if (StringUtils.isNotBlank(max) && ApiVersionUtil.compareVersion(version, max) > 0) {
                    throw new ApiVersionException(202002, "当前应用不兼容低版本");
                }
                // 判断开始时间区间
                if (StringUtils.isNotBlank(start)) {
                    Date date = DateUtils.parseDate(start);
                    if (System.currentTimeMillis() < date.getTime()) {
                        throw new ApiVersionException(202003, "当前API尚未开放");
                    }
                }
                // 判断介绍时间区间
                if (StringUtils.isNotBlank(end)) {
                    Date date = DateUtils.parseDate(end);
                    if (System.currentTimeMillis() > date.getTime()) {
                        throw new ApiVersionException(202004, "当前API已关闭");
                    }
                }
            }
        }
    }

}
